package pl.textureStudio.view.panel.edit
{
	import pl.textureStudio.data.vo.StudioTextureVO;
	import pl.textureStudio.model.StudioModel;
	import pl.textureStudio.view.panel.base.BasePanel;
	import pl.textures.TextureType;

	import com.bit101.components.CheckBox;
	import com.bit101.components.ComboBox;
	import com.bit101.components.Label;
	import com.bit101.components.PushButton;
	import com.bit101.components.RadioButton;

	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.text.TextFieldAutoSize;

	/**
	 * @author michalr
	 */
	public class TextureEditPanel extends BasePanel
	{
		private var frame:Shape;
		private var panel:Shape;
		private var packMask:Shape;
		private var textureView:TextureView;
		private var currentTexture:StudioTextureVO;
		private var texturePackSettingsEnabled:Boolean;
		// ...
		private var tName:Label;
		private var cbType:ComboBox;
		private var rbOrigLayer:RadioButton;
		private var rbCollisiongLayer:RadioButton;
		private var rbDepthSortinggLayer:RadioButton;
		private var bShowGrid:PushButton;
		private var bShowMask:PushButton;
		private var bSave:PushButton;
		private var bClose:PushButton;
		private var isTexturePackResident:CheckBox;
		// ...
		private var guideV1:GuideData;
		private var guideV2:GuideData;
		private var guideH1:GuideData;
		private var guideH2:GuideData;
		// ...
		private static const FRAME_SIZE:uint = 10;
		internal static const PANEL_W:uint = 150;

		public function TextureEditPanel()
		{
			super();
		}

		override protected function init():void
		{
			frame = new Shape();
			panel = new Shape();
			packMask = new Shape();

			addChild( frame );
			addChild( panel );
			currentTexture = StudioModel.getInstance().currentEditedTexture;
			var g:Graphics;
			if ( currentTexture != null)
			{
				if (currentTexture.textureSize.y > (size.y - FRAME_SIZE * 2))
					size.y = currentTexture.textureSize.y - FRAME_SIZE * 2;
				if (currentTexture.textureSize.x > (size.x - 170))
					size.x = currentTexture.textureSize.x + 170;
				textureView = TextureView.factory( currentTexture );
				textureView.x = 160 + Math.floor( (size.x - 160 - FRAME_SIZE ) * .5 ) - textureView.getSize().x * .5;
				textureView.y = Math.floor( (size.y - currentTexture.textureSize.y) * .5 );
				addChild( textureView );
				addChild( packMask );
			}
			g = panel.graphics;
			g.beginFill( 0x333333 );
			g.drawRect( FRAME_SIZE, FRAME_SIZE, PANEL_W, size.y - FRAME_SIZE * 2 );
			g.endFill();
			// ...
			g = frame.graphics;
			g.beginFill( 0, 1 );
			g.drawRect( 0, 0, size.x, size.y );
			g.drawRect( FRAME_SIZE, FRAME_SIZE, size.x - FRAME_SIZE * 2, size.y - FRAME_SIZE * 2 );
			g.endFill();
			g.beginFill( 0x3A3A3A, .9 );
			g.drawRect( FRAME_SIZE, FRAME_SIZE, size.x - FRAME_SIZE * 2, size.y - FRAME_SIZE * 2 );
			g.endFill();
			// ...
			var leftMargin:uint = 15;
			var topMargin:uint = FRAME_SIZE;

			// ...

			var sectionMainInfo:UISection = new UISection( this, FRAME_SIZE, topMargin, PANEL_W, 'Main info' );
			tName = new Label( this, leftMargin, 0, currentTexture.textureID );
			tName.autoSize = true;
			tName.textField.textColor = 0xFFFFFF;
			cbType = new ComboBox( this, leftMargin, 0, "Texture type" );
			cbType.addItem( {label:'Tile', data:TextureType.TILE} );
			cbType.addItem( {label:'Static obstacle', data:TextureType.STATIC_OBSTACLE} );
			cbType.addEventListener( Event.SELECT, onTextureTypeSelect );
			sectionMainInfo.setComponent( tName, 0 );
			sectionMainInfo.setComponent( cbType, 25 );

			// ...

			var sectionLayers:UISection = new UISection( this, FRAME_SIZE, 100, PANEL_W, 'Layers' );
			rbOrigLayer = new RadioButton( this, leftMargin, 0, 'Original layer' );
			rbCollisiongLayer = new RadioButton( this, leftMargin, 0, 'Collision layer' );
			rbDepthSortinggLayer = new RadioButton( this, leftMargin, 0, 'Depthsorting layer' );
			rbOrigLayer.groupName = rbCollisiongLayer.groupName = rbDepthSortinggLayer.groupName = 'layers';
			sectionLayers.setComponent( rbOrigLayer, 0 );
			sectionLayers.setComponent( rbCollisiongLayer, 20 );
			sectionLayers.setComponent( rbDepthSortinggLayer, 40 );

			// ...

			var sectionTPack:UISection = new UISection( this, FRAME_SIZE, 290, PANEL_W, 'Texture pack settings' );
			isTexturePackResident = new CheckBox( this, leftMargin, 0, 'Texture pack resident', onTpPress );
			bShowGrid = new PushButton( this, leftMargin, 0, 'Show guides', onShowGuides );
			bShowGrid.toggle = true;
			bShowMask = new PushButton( this, leftMargin, 0, 'Show mask', onShowMask );
			bShowMask.toggle = true;
			sectionTPack.setComponent( isTexturePackResident, 0 );
			sectionTPack.setComponent( bShowGrid, 20 );
			sectionTPack.setComponent( bShowMask, 50 );

			// ...

			var sectionCloseSave:UISection = new UISection( this, FRAME_SIZE, 392, PANEL_W, 'Options' );
			bClose = new PushButton( this, leftMargin, 0, 'Close ', onClosePanel );
			bClose.setSize( 40, bClose.height );
			bSave = new PushButton( this, leftMargin + 75, 0, 'Save', onClosePanel );
			bSave.setSize( 40, bSave.height );
			sectionCloseSave.setComponent( bClose, 0 );
			sectionCloseSave.setComponent( bSave, 0 );

			// ...

			guideV1 = new GuideData( this, GuideData.V, 190, size.y - 20 );
			guideV1.setPressHandler( onGuidePress );
			guideV1.setReleaseHandler( onGuideRelease );

			guideV2 = new GuideData( this, GuideData.V, 250, size.y - 20 );
			guideV2.setPressHandler( onGuidePress );
			guideV2.setReleaseHandler( onGuideRelease );

			guideH1 = new GuideData( this, GuideData.H, 250, size.x - PANEL_W - FRAME_SIZE * 2 );
			guideH1.setPressHandler( onGuidePress );
			guideH1.setReleaseHandler( onGuideRelease );

			guideH2 = new GuideData( this, GuideData.H, 200, size.x - PANEL_W - FRAME_SIZE * 2 );
			guideH2.setPressHandler( onGuidePress );
			guideH2.setReleaseHandler( onGuideRelease );

			// ... config

			if (currentTexture.textureType == TextureType.TILE)
				cbType.selectedIndex = 0;
			if (currentTexture.textureType == TextureType.STATIC_OBSTACLE)
				cbType.selectedIndex = 1;
			if (currentTexture.texturePackRegion != null)
			{
				isTexturePackResident.selected = true;

				updateTexturePackSettings();
				textureView.mask = packMask;

				// ...
				var r:Rectangle = currentTexture.texturePackRegion;
				guideV1.setVal( textureView.x + r.x );
				guideV2.setVal( textureView.x + r.x + r.width );
				guideH1.setVal( textureView.y + r.y );
				guideH2.setVal( textureView.y + r.y + r.height );
				drawMask();
			}
			else
			{
				isTexturePackResident.selected = false;
				bShowGrid.visible = false;
				bShowGrid.selected = false;
				onShowGuides();
			}

			realign();
		}

		private function onClosePanel( e:MouseEvent ):void
		{
			StudioModel.getInstance().closePanel();
		}

		private function onShowMask( e:MouseEvent ):void
		{
			textureView.mask = bShowMask.selected ? packMask : null;
		}

		private function onShowGuides( e:MouseEvent = null ):void
		{
			guideH1.enabled = guideH2.enabled = guideV1.enabled = guideV2.enabled = bShowGrid.selected;
		}

		private function onGuideRelease( guide:Sprite = null ):void
		{
			guide.stopDrag();
			removeEventListener( MouseEvent.MOUSE_MOVE, onMM );
			if (bShowMask.selected == true)
			{
				drawMask();
				textureView.mask = packMask;
			}
		}

		private function drawMask():void
		{
			packMask.graphics.clear();
			packMask.graphics.beginFill( 0, .5 );
			var px:uint = Math.min( guideV1.val, guideV2.val );
			var py:uint = Math.min( guideH1.val, guideH2.val );
			var px2:uint = Math.max( guideV1.val, guideV2.val );
			var py2:uint = Math.max( guideH1.val, guideH2.val );
			packMask.graphics.drawRect( px, py, px2 - px, py2 - py );
			packMask.graphics.endFill();
		}

		private function onGuidePress( guide:Sprite ):void
		{
			addEventListener( MouseEvent.MOUSE_MOVE, onMM );
			textureView.mask = null;
			var r:Rectangle;
			if (guide.height > guide.width)
			{
				var w:uint = size.x - (PANEL_W + FRAME_SIZE * 2);
				r = new Rectangle( PANEL_W + FRAME_SIZE, FRAME_SIZE, w, 0 );
			}
			else
			{
				var h:uint = size.y - (FRAME_SIZE * 2);
				r = new Rectangle( PANEL_W + FRAME_SIZE, FRAME_SIZE, 0, h );
			}
			guide.startDrag( false, r );
		}

		private function onMM( event:MouseEvent ):void
		{
			drawMask();
		}

		private function onTpPress( e:MouseEvent ):void
		{
			updateTexturePackSettings();
		}

		private function onTextureTypeSelect( event:Event ):void
		{
			handleTextureTypeChange();
		}

		private function updateTexturePackSettings():void
		{
			isTexturePackResident.enabled = texturePackSettingsEnabled;
			bShowGrid.enabled = isTexturePackResident.selected && texturePackSettingsEnabled;
			bShowMask.enabled = isTexturePackResident.selected && texturePackSettingsEnabled;
			bShowGrid.selected = isTexturePackResident.selected && texturePackSettingsEnabled;
			if (isTexturePackResident.selected == true)
			{
				textureView.mask = packMask;
				packMask.visible = true;
				bShowGrid.selected = true;
				bShowMask.selected = true;
			}
			else
			{
				packMask.visible = false;
				textureView.mask = null;
				bShowGrid.selected = false;
				bShowMask.selected = false;
			}
			onShowGuides();
		}

		private function updateLayerChoser():void
		{
		}

		private function handleTextureTypeChange():void
		{
			if (cbType.selectedItem['data'] == TextureType.STATIC_OBSTACLE)
			{
				texturePackSettingsEnabled = true;
				rbCollisiongLayer.enabled = true;
				rbDepthSortinggLayer.enabled = true;
				isTexturePackResident.selected = true;
			}
			else
			{
				texturePackSettingsEnabled = false;
				rbCollisiongLayer.enabled = false;
				rbDepthSortinggLayer.enabled = false;
				isTexturePackResident.selected = false;
			}
			rbOrigLayer.selected = true;
			updateTexturePackSettings();
			updateLayerChoser();
		}

		override public function hide():void
		{
		}
	}
}
import com.bit101.components.Component;
import com.bit101.components.Label;

import flash.display.DisplayObjectContainer;
import flash.display.LineScaleMode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.MouseEvent;

class GuideData
{
	public static const V:uint = 0;
	public static const H:uint = 1;
	public var type:uint;
	public var dim:uint;
	private var _val:uint;
	private var guide:Sprite;
	private var line:Shape;
	private var pressHandler:Function;
	private var releaseHandler:Function;
	private var isPressed:Boolean;

	public function GuideData( parent:DisplayObjectContainer, type:uint, val:uint, dim:uint )
	{
		line = new Shape();
		this.type = type;
		this.dim = dim;
		_val = val;

		guide = new Sprite();
		guide.addChild( line );
		parent.addChild( guide );
		guide.buttonMode = true;
		if (type == V)
		{
			guide.x = val;
			guide.y = 10;
		}
		else
		{
			guide.x = 150 + 10;
			guide.y = val;
		}

		line.graphics.beginFill( 0, 0 );
		line.graphics.drawRect( type == V ? -10 : 0, type == V ? 0 : -10, type == V ? 20 : dim, type == V ? dim : 20 );
		line.graphics.endFill();

		line.graphics.lineStyle( 1, 0xFFFFFF, 1, false, LineScaleMode.NONE );
		line.graphics.moveTo( type == V ? 0 : 0, type == V ? 0 : 0 );
		line.graphics.lineTo( type == V ? 0 : dim, type == V ? dim : 0 );
		// ...

		guide.addEventListener( MouseEvent.MOUSE_DOWN, onMD );
		parent.stage.addEventListener( MouseEvent.MOUSE_UP, onMUp );
	}

	private function onMUp( event:MouseEvent ):void
	{
		if (isPressed == true)
		{
			isPressed = false;
			releaseHandler( guide );
		}
	}

	private function onMD( event:MouseEvent ):void
	{
		isPressed = true;
		pressHandler( guide );
	}

	public function setVal( val:uint ):void
	{
		_val = val;
		if (type == V)
			guide.x = val;
		else
			guide.y = val;
	}

	public function get val():uint
	{
		if (type == V)
			return guide.x;
		else
			return guide.y;
	}

	function setPressHandler( f:Function ):void
	{
		pressHandler = f;
	}

	function setReleaseHandler( f:Function ):void
	{
		releaseHandler = f;
	}

	function set enabled( val:Boolean ):void
	{
		guide.visible = val;
	}
}
class UISection extends Sprite
{
	private var sectionLine:Shape;
	private var topMargin:uint;
	private var w:uint;
	private var label:Label;

	public function UISection( parent:DisplayObjectContainer, px:uint, py:uint, w:uint, sectionName:String )
	{
		y = py;
		x = px;
		parent.addChild( this );
		sectionLine = new Shape();
		sectionLine.graphics.lineStyle( 1, 0x1E1E1E, 1, false, 'none' );
		sectionLine.graphics.lineTo( w, 0 );
		sectionLine.graphics.moveTo( 0, 1 );
		sectionLine.graphics.lineStyle( 1, 0x4D4D4D, 1, false, 'none' );
		sectionLine.graphics.lineTo( w, 1 );
		label = new Label( this, 0, 1, sectionName );
		sectionLine.graphics.moveTo( 0, Math.floor( label.y + label.height ) );
		sectionLine.graphics.lineStyle( 1, 0x4D4D4D, 1, false, 'none' );
		sectionLine.graphics.lineTo( w, Math.floor( label.y + label.height ) );
		addChild( sectionLine );
		topMargin = 5;
		this.w = w;
	}

	public function setComponent( component:Component, py:Number ):void
	{
		addChild( component );
		component.y = py + topMargin + label.y + label.height;
	}
}
